package main

import (
	"fmt"
	"grpc-go-demo/echo"
	"io"
	"log"
	"net"
	"sync"

	"google.golang.org/grpc"
)

type EchoImpl struct {
	echo.UnimplementedEchoServer
}

func (e *EchoImpl) BidirectStreamEcho(stream echo.Echo_BidirectStreamEchoServer) error {
	var wg sync.WaitGroup
	msgCh := make(chan string)
	wg.Add(1)
	go func() {
		defer wg.Done()
		for v := range msgCh {
			err := stream.Send(&echo.EchoResponse{Message: v})
			if err != nil {
				fmt.Println(err.Error())
				continue
			}
		}
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		for {
			req, err := stream.Recv()
			if err == io.EOF {
				break
			}
			if err != nil {
				log.Fatalln(err.Error())
			}
			fmt.Println("received:", req.GetMessage())
			msgCh <- req.GetMessage()
		}
		close(msgCh)
	}()
	wg.Wait()
	return nil
}

func main() {
	listener, err := net.Listen("tcp", ":8080")
	if err != nil {
		log.Fatal(err.Error())
	}
	defer listener.Close()

	grpcServer := grpc.NewServer()

	echo.RegisterEchoServer(grpcServer, &EchoImpl{})

	fmt.Println("bidirect server start at 8080:")

	grpcServer.Serve(listener)
}
